package framework;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
 * This is a listener class that handles mouse events
 * 
 */
public class DisplayUtilMouse implements MouseListener, MouseMotionListener {
	// Start is true when in draw mode
	private boolean start = false;
	// Active is true when mouse in within board bounds and is able to draw
	private boolean active = true;

	private AutomatonPluginInterface ap;
	private DisplayUtilStage stage;

	// Current selected state
	private int state;

	/**
	 * Constructor that initializes fields
	 * 
	 * @param AutomatonPlugin ap - the automaton plugin
	 * @param DisplayUtilStage stage - the stage where the display is shown and managed
	 */
	public DisplayUtilMouse(AutomatonPluginInterface ap, DisplayUtilStage stage) {
		this.ap = ap;
		this.stage = stage;
	}

	
	/**
	 * Handles mouse clicked events
	 */
	@Override
	public void mouseClicked(MouseEvent e) {
		if (start && active) {
			// Get position of mouse
			int x = e.getX();
			int y = e.getY();
			int row = (ap.getBoard().getTotalRowNum() * y)
					/ stage.getPane().getHeight();
			int col = (ap.getBoard().getTotalColNum() * x)
					/ stage.getPane().getWidth();
			// If mouse is within board bounds
			if (0 <= col && col < ap.getBoard().getTotalColNum() && 0 <= row
					&& row < ap.getBoard().getTotalRowNum()) {
				// Get cell that mouse is pointing to
				CellInterface target = ap.getBoard().getTargetCell(row, col);
				// Set cell state to current state
				target.setState(state);
				// Redraw
				stage.redraw();
			}
		}
	}

	
	/**
	 * Mouse entered board bounds
	 */
	@Override
	public void mouseEntered(MouseEvent e) {
		if (start) {
			active = true;
		}
	}

	
	/**
	 * Mouse left board bounds
	 */
	@Override
	public void mouseExited(MouseEvent e) {
		if (start) {
			active = false;
		}
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// not used, do nothing
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// not used, do nothing
	}

	// Set start to true when in draw mode
	public void setControl(boolean ctrl) {
		start = ctrl;
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// not used, do nothing
	}

	
	/**
	 * Handle mouse dragged events
	 */
	@Override
	public void mouseDragged(MouseEvent e) {
		if (start && active) {
			// Get position of mouse
			int x = e.getX();
			int y = e.getY();
			int row = (ap.getBoard().getTotalRowNum() * y)
					/ stage.getPane().getHeight();
			int col = (ap.getBoard().getTotalColNum() * x)
					/ stage.getPane().getWidth();
			// If mouse is within board bounds
			if (0 <= col && col < ap.getBoard().getTotalColNum() && 0 <= row
					&& row < ap.getBoard().getTotalRowNum()) {
				// Get cell that mouse is pointing to
				CellInterface target = ap.getBoard().getTargetCell(row, col);
				// Set cell state to current state
				target.setState(state);
				// Redraw
				stage.redraw();
			}
		}
	}

	/**
	 * Set current state
	 * 
	 * @param int state - the state that the current drawn cells will have
	 */
	public void setDrawState(int state) {
		this.state = state;
	}

}
